"""
循环嵌套
学习目标：
1. 理解循环嵌套的概念
2. 掌握二重循环的使用
3. 掌握多重循环的使用
4. 学会在实际场景中应用嵌套循环
"""

# ==================== 1. 循环嵌套基础 ====================
print("=" * 50)
print("1. 循环嵌套基础")
print("=" * 50)

print("基本结构：")
print("""
for i in 外层序列:
    for j in 内层序列:
        循环体
""")

print("\n简单示例：")
for i in range(1, 4):  # 外层循环3次
    for j in range(1, 3):  # 内层循环2次
        print(f"  i={i}, j={j}")

print("\n💡 执行流程：")
print("  - 外层循环一次，内层循环完整执行一遍")
print("  - 总执行次数 = 外层次数 × 内层次数")
print("  - 上例：3 × 2 = 6次")

print()

# ==================== 2. 打印矩形 ====================
print("=" * 50)
print("2. 实战：打印矩形")
print("=" * 50)

rows = 4
cols = 6

print(f"{rows}行{cols}列的矩形：")
for i in range(rows):
    for j in range(cols):
        print("* ", end="")
    print()  # 每行结束换行

print()

# ==================== 3. 打印三角形 ====================
print("=" * 50)
print("3. 实战：打印三角形")
print("=" * 50)

# 直角三角形
print("直角三角形：")
for i in range(1, 6):
    for j in range(i):
        print("* ", end="")
    print()

print()

# 倒直角三角形
print("倒直角三角形：")
for i in range(5, 0, -1):
    for j in range(i):
        print("* ", end="")
    print()

print()

# 等腰三角形
print("等腰三角形：")
for i in range(1, 6):
    # 打印空格
    for j in range(5 - i):
        print("  ", end="")
    # 打印星号
    for j in range(2 * i - 1):
        print("* ", end="")
    print()

print()

# ==================== 4. 九九乘法表 ====================
print("=" * 50)
print("4. 实战：九九乘法表")
print("=" * 50)

for i in range(1, 10):
    for j in range(1, i + 1):
        print(f"{j}×{i}={i*j:2d}", end="  ")
    print()

print()

# ==================== 5. 遍历二维列表 ====================
print("=" * 50)
print("5. 实战：遍历二维列表（矩阵）")
print("=" * 50)

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

print("矩阵：")
for row in matrix:
    for element in row:
        print(f"{element:3d}", end=" ")
    print()

print("\n矩阵所有元素：")
for i in range(len(matrix)):
    for j in range(len(matrix[i])):
        print(f"  matrix[{i}][{j}] = {matrix[i][j]}")

print()

# ==================== 6. 打印数字金字塔 ====================
print("=" * 50)
print("6. 实战：数字金字塔")
print("=" * 50)

n = 5
for i in range(1, n + 1):
    # 打印空格
    for j in range(n - i):
        print("  ", end="")
    # 打印递增数字
    for j in range(1, i + 1):
        print(f"{j} ", end="")
    # 打印递减数字
    for j in range(i - 1, 0, -1):
        print(f"{j} ", end="")
    print()

print()

# ==================== 7. 查找二维列表中的元素 ====================
print("=" * 50)
print("7. 实战：在二维列表中查找元素")
print("=" * 50)

matrix = [
    [10, 20, 30],
    [40, 50, 60],
    [70, 80, 90]
]

target = 50

print("矩阵：")
for row in matrix:
    print(f"  {row}")

print(f"\n查找目标：{target}")

found = False
for i in range(len(matrix)):
    for j in range(len(matrix[i])):
        if matrix[i][j] == target:
            print(f"✅ 找到了！位置：[{i}][{j}]")
            found = True
            break
    if found:
        break  # 外层也要break

if not found:
    print(f"❌ 未找到{target}")

print()

# ==================== 8. 计算矩阵的和 ====================
print("=" * 50)
print("8. 实战：计算矩阵所有元素的和")
print("=" * 50)

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

print("矩阵：")
for row in matrix:
    print(f"  {row}")

total = 0
for row in matrix:
    for element in row:
        total += element

print(f"\n所有元素的和：{total}")

# 每行的和
print("\n每行的和：")
for i, row in enumerate(matrix):
    row_sum = sum(row)
    print(f"  第{i+1}行：{row_sum}")

# 每列的和
print("\n每列的和：")
for j in range(len(matrix[0])):
    col_sum = 0
    for i in range(len(matrix)):
        col_sum += matrix[i][j]
    print(f"  第{j+1}列：{col_sum}")

print()

# ==================== 9. 生成组合 ====================
print("=" * 50)
print("9. 实战：生成所有两数组合")
print("=" * 50)

list1 = ["A", "B", "C"]
list2 = [1, 2, 3]

print(f"列表1：{list1}")
print(f"列表2：{list2}")
print("\n所有组合：")

for item1 in list1:
    for item2 in list2:
        print(f"  ({item1}, {item2})")

print()

# ==================== 10. 打印日历表格 ====================
print("=" * 50)
print("10. 实战：打印月历（简化版）")
print("=" * 50)

# 假设某月有31天，1号是周三（2）
days_in_month = 31
first_day = 2  # 0=周日, 1=周一, ..., 6=周六

print("  日  一  二  三  四  五  六")
print("-" * 35)

# 打印第一周的空格
for i in range(first_day):
    print("    ", end="")

# 打印日期
day = 1
while day <= days_in_month:
    print(f"{day:3d} ", end="")
    
    # 计算当前是周几
    current_day = (first_day + day - 1) % 7
    
    # 周六换行
    if current_day == 6:
        print()
    
    day += 1

print("\n")

# ==================== 11. 找出所有质数对 ====================
print("=" * 50)
print("11. 实战：找出50以内的质数对（差为2）")
print("=" * 50)

def is_prime(n):
    if n < 2:
        return False
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    return True

print("质数对（差为2的质数）：")
for i in range(2, 50):
    if is_prime(i) and is_prime(i + 2):
        print(f"  ({i}, {i+2})")

print()

# ==================== 12. 学生成绩表 ====================
print("=" * 50)
print("12. 实战：学生成绩表分析")
print("=" * 50)

students = [
    ["张三", 85, 90, 78],
    ["李四", 92, 88, 95],
    ["王五", 78, 85, 82],
]

subjects = ["语文", "数学", "英语"]

print("成绩表：")
print(f"{'姓名':<8} {'语文':>6} {'数学':>6} {'英语':>6} {'总分':>6} {'平均':>6}")
print("-" * 50)

for student in students:
    name = student[0]
    scores = student[1:]
    total = sum(scores)
    average = total / len(scores)
    
    print(f"{name:<8} ", end="")
    for score in scores:
        print(f"{score:>6}", end=" ")
    print(f"{total:>6} {average:>6.1f}")

print("-" * 50)

# 计算每科平均分
print("\n各科平均分：")
for j in range(len(subjects)):
    subject_total = 0
    for i in range(len(students)):
        subject_total += students[i][j + 1]
    subject_avg = subject_total / len(students)
    print(f"  {subjects[j]}：{subject_avg:.1f}分")

print()

# ==================== 13. 打印字符图案 ====================
print("=" * 50)
print("13. 实战：打印字符图案")
print("=" * 50)

# 空心矩形
print("空心矩形：")
rows, cols = 5, 8
for i in range(rows):
    for j in range(cols):
        if i == 0 or i == rows - 1 or j == 0 or j == cols - 1:
            print("* ", end="")
        else:
            print("  ", end="")
    print()

print()

# 菱形
print("菱形：")
n = 5
# 上半部分
for i in range(n):
    for j in range(n - i - 1):
        print(" ", end="")
    for j in range(2 * i + 1):
        print("*", end="")
    print()
# 下半部分
for i in range(n - 2, -1, -1):
    for j in range(n - i - 1):
        print(" ", end="")
    for j in range(2 * i + 1):
        print("*", end="")
    print()

print()

# ==================== 14. 三重循环 ====================
print("=" * 50)
print("14. 三重循环示例")
print("=" * 50)

print("三维坐标点（1-3范围）：")
count = 0
for x in range(1, 4):
    for y in range(1, 4):
        for z in range(1, 4):
            count += 1
            print(f"  ({x},{y},{z})", end="")
            if count % 6 == 0:
                print()

print(f"\n\n总共{count}个坐标点（3³ = 27）")

print()

# ==================== 15. 实战：找出完全数 ====================
print("=" * 50)
print("15. 实战：找出1000以内的完全数")
print("=" * 50)

print("完全数：所有真因子（除自身外的因子）之和等于它本身")
print("\n1000以内的完全数：")

for num in range(2, 1001):
    # 找出所有因子
    factors = []
    for i in range(1, num):
        if num % i == 0:
            factors.append(i)
    
    # 判断是否为完全数
    if sum(factors) == num:
        print(f"  {num} = {' + '.join(map(str, factors))}")

print()

# ==================== 16. 购物组合 ====================
print("=" * 50)
print("16. 实战：购物组合推荐")
print("=" * 50)

shirts = ["白衬衫", "黑T恤", "蓝衬衫"]
pants = ["牛仔裤", "休闲裤"]
shoes = ["运动鞋", "皮鞋"]

print("上衣：", shirts)
print("裤子：", pants)
print("鞋子：", shoes)
print("\n所有搭配组合：")

combo_num = 1
for shirt in shirts:
    for pant in pants:
        for shoe in shoes:
            print(f"  组合{combo_num}：{shirt} + {pant} + {shoe}")
            combo_num += 1

total_combos = len(shirts) * len(pants) * len(shoes)
print(f"\n共{total_combos}种搭配")

print()

# ==================== 总结 ====================
print("=" * 50)
print("✨ 循环嵌套总结")
print("=" * 50)
print("""
1. 基本结构：
   for i in 外层:
       for j in 内层:
           循环体

2. 执行规则：
   ✅ 外层循环一次，内层循环完整执行
   ✅ 总次数 = 外层次数 × 内层次数
   ✅ 可以有多重嵌套

3. 常见应用：
   - 打印图案（矩形、三角形、菱形）
   - 九九乘法表
   - 遍历二维列表（矩阵）
   - 生成组合
   - 复杂的查找和统计

4. 二维列表：
   matrix = [[1,2,3], [4,5,6], [7,8,9]]
   
   # 遍历
   for row in matrix:
       for element in row:
           print(element)
   
   # 带索引
   for i in range(len(matrix)):
       for j in range(len(matrix[i])):
           print(matrix[i][j])

5. 嵌套循环中的break：
   - break只跳出当前循环
   - 要跳出外层需要标志变量或额外break

   found = False
   for i in range(n):
       for j in range(m):
           if 条件:
               found = True
               break
       if found:
           break

6. 性能考虑：
   ⚠️ 嵌套层数越多，时间复杂度越高
   ⚠️ 二重循环：O(n²)
   ⚠️ 三重循环：O(n³)
   ⚠️ 尽量减少不必要的嵌套

7. 最佳实践：
   - 使用有意义的循环变量名
   - 适当的缩进保持可读性
   - 复杂嵌套考虑提取为函数
   - 能用单层循环就不用嵌套
   - 注释说明嵌套的目的
""")
print("=" * 50)

